package com.imooc.systemwidget;

import android.content.Context;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.Scroller;

public class MyScrollView extends ViewGroup {

    private int mScreenHeight;
    private Scroller mScroller;
    private int mLastY;
    private int mStart;
    private int mEnd;

    private final String TAG = "MyScrollView";

    public MyScrollView(Context context) {
        super(context);
        initView(context);
    }

    public MyScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView(context);
    }

    public MyScrollView(Context context, AttributeSet attrs,
                        int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(context);
    }

    private void initView(Context context) {
        WindowManager wm = (WindowManager) context.getSystemService(
                Context.WINDOW_SERVICE);
        DisplayMetrics dm = new DisplayMetrics();        //DisplayMetrics.“显示指标”
        wm.getDefaultDisplay().getMetrics(dm);          //wm * get默认显示 * get指标
        mScreenHeight = dm.heightPixels;
        mScroller = new Scroller(context);          //**********Scroller.java,
                        // 整个ViewGroup作为一个Scroller对象，所以startScroll的第二个参数--startY
                        // 恒以整个ViewGroup的上边界（也即第一个子view的上边界）为0*********//
    }

//    public ViewGroup.LayoutParams getLayoutParams() {
//        return mLayoutParams;
//    }
//Description copied from class: View Called from layout when this view should assign a
// size and position to each of its children. Derived classes with children should
// override this method and call layout on each of their children.
//    Specified by:
//    onLayout in class ViewGroup
//Parameters:
//    changed - This is a new size or position for this view
//    l - Left position, relative to parent
//    t - Top position, relative to parent
//    r - Right position, relative to parent
//    b - Bottom position, relative to parent

    @Override
    protected void onLayout(boolean changed,
                            int l, int t, int r, int b) {
        int childCount = getChildCount();
        // 设置ViewGroup的高度
        MarginLayoutParams mlp = (MarginLayoutParams) getLayoutParams();
        mlp.height = mScreenHeight * childCount;  //DisplayMetrics->>>heightPixels->>mScreenHeight
        setLayoutParams(mlp);
        for (int i = 0; i < childCount; i++) {
            View child = getChildAt(i);
            if (child.getVisibility() != View.GONE) {
                child.layout(l, i * mScreenHeight,
                        r, (i + 1) * mScreenHeight);
            }
        }
    }

//    public View getChildAt(int index) {
//        if (index < 0 || index >= mChildrenCount) {
//            return null;
//        }
//        return mChildren[index];
//    }

    @Override
    protected void onMeasure(int widthMeasureSpec,
                             int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int count = getChildCount();    //ViewGruop.java.getChildCount   * Returns the number of children in the group.//
        for (int i = 0; i < count; ++i) {
            View childView = getChildAt(i);
            measureChild(childView,
                    widthMeasureSpec, heightMeasureSpec);//******************************//
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int y = (int) event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mLastY = y;
                mStart = getScrollY();
                break;
            case MotionEvent.ACTION_MOVE:
                if (!mScroller.isFinished()) {
                    mScroller.abortAnimation();
                }
                int dy = mLastY - y;
                if (getScrollY() < 0) {
                    dy = 0;
                }
                int n = getHeight() - mScreenHeight;//getHeight()乃是整个ViewGroup的长度
//                Log.d(TAG, "debug getHeight():  "+ getHeight());
//                Log.d(TAG, "debug mScreenHeight: " + mScreenHeight);
//                Log.d(TAG, "debug: getHeight() - mScreenHeight"+ n );
//                Log.d(TAG, "debug getScrollY(): " + getScrollY());
                if (getScrollY() > getHeight() - mScreenHeight) {
                    dy = 0;
                }
                scrollBy(0, dy);
                mLastY = y;
                break;
            case MotionEvent.ACTION_UP:
                int dScrollY = checkAlignment();
                if (dScrollY > 0) {
                    if (dScrollY < mScreenHeight / 3) {
                        mScroller.startScroll( //startScroll的function解释见下方!!!!!!!!!!!!!!!!!!!
                                0, getScrollY(),
                                0, -dScrollY);
                    } else {
                        mScroller.startScroll(
                                0, getScrollY(),
                                0, mScreenHeight - dScrollY);
                    }
                } else {
                    if (-dScrollY < mScreenHeight / 3) {
                        mScroller.startScroll(
                                0, getScrollY(),
                                0, -dScrollY);
                    } else {
                        mScroller.startScroll(
                                0, getScrollY(),
                                0, -mScreenHeight - dScrollY);
                    }
                }
                break;
        }
        postInvalidate();//没加这行code待会儿滑划动!!!!!!!!!!!!!!!!!!!!
        return true;
    }

//    1.startScroll的第二个参数--startY             !!!!!!!!!!!!!!!!!!!!!!!!!!
//    恒以整个ViewGroup的上边界（也即第一个子view的上边界）为0*********
//    2.并且，startX=0时，startY 的所谓 start ，是指把ContentView的上边界线为 start line ，!!!!!!!!
//    即startScroll的func是将ViewGroup的点（0，startY）的位置放在ContentView的上边界线处，!!!!!!!!!!!!!!!!!!!!!!
//    随后再滑动一个(dx,dy)量
//    ------》》这里把上边第一个startScroll的第二个参数改成0，再debug一下便可理解!!!!!!!!
//    debug的时候，将第一个子view上拉一个(< mScreenHeight / 3)的距离，放手之后会发现子view上方出现了一个空白区域，
//    原因便是刚刚设置的start=0Y把ViewGroup的上边界(0,0)放在了ContentView的上边界线上，
//    再根据参数-dScrollY下滑了一段距离，形成空白区域
//    /**
//     * Start scrolling by providing a starting point and the distance to travel.
//     * The scroll will use the default value of 250 milliseconds for the
//     * duration.
//     *
//     * @param startX Starting horizontal scroll offset in pixels. Positive
//     *        numbers will scroll the content to the left.
//     * @param startY Starting vertical scroll offset in pixels. Positive numbers
//     *        will scroll the content up.
//     * @param dx Horizontal distance to travel. Positive numbers will scroll the
//     *        content to the left.        正数将内容滚动到左边!!!!!!!!!!!!!!!!!!!!
//     * @param dy Vertical distance to travel. Positive numbers will scroll the
//     *        content up.                  正数将内容滚动到!!!!!!!!!!!!!!!!!!!!!!!!!
//     */
//    public void startScroll(int startX, int startY, int dx, int dy) {
//        startScroll(startX, startY, dx, dy, DEFAULT_DURATION);
//    }

	private int checkAlignment() {
        int mEnd = getScrollY();//ViewGroup的上边界（也即第一个子view的上边界）距离ContentView上边界的偏移量（自己debug便知晓）
        boolean isUp = ((mEnd - mStart) > 0);
//        Log.d(TAG, "debugmStart: "+ mStart );
//        Log.d(TAG, "debug mEnd: " + mEnd);
        int lastPrev = mEnd % mScreenHeight;
        int lastNext = mScreenHeight - lastPrev;
        if (isUp) {
            //向上的
            return lastPrev;
        } else {
            return -lastNext;
        }
    }
    @Override
    public void computeScroll() { //去掉此func，滑动功能跟黏性（其实也是滑动)将出现问题
        super.computeScroll();
        if (mScroller.computeScrollOffset()) {
            scrollTo(0, mScroller.getCurrY());//滑动!!!!!!!!!!!!!!!
            postInvalidate();
        }
    }
}
